// ml278
// Copyright (C) 2008 Bjørn Øivind Bjørnsen, Aleksander Gjermundsen, Knut Andre Tidemann, Thomas Hansen
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

#ifndef __PLANETARYHEIGHTMAPDATA_H_
#define __PLANETARYHEIGHTMAPDATA_H_

#include <list>
#include <math.h>
#include <OgreVector3.h>
#include "planetarypageheightmap.h"
#include "planetaryzoneheightmap.h"

namespace Ogre
{
	class PlanetarySceneManager;
	class PlanetaryOptions;

	/**
	* Class used for reading heightmaps.
	* This class reads the heightmap resources and caches them.
	*/
	class PlanetaryHeightmapData
	{
	private:
		/**
		* Internal struct used for keeping cached heightmap data. Used by pages / tiles.
		*/
		struct HEIGHTMAPDATA
		{
			unsigned int planet;	/// Planet ID
			unsigned int zone;	/// Zone ID
			unsigned int pageX;	/// Page index X
			unsigned int pageZ;	/// Page index Z
			unsigned int LOD;	/// Level of detail of the heightmap

			/// Pointer to the class that handles the actual heightmap data
			PlanetaryPageHeightmap *heightmap;
		};

		/**
		* Internal struct used for keeping cached heightmap data. Used by zones.
		*/
		struct ZONEHEIGHTMAPDATA
		{
			unsigned int planet;
			unsigned int zone;

			PlanetaryZoneHeightmap *heightmap;
		};
	public:
		PlanetaryHeightmapData(PlanetarySceneManager *mgr);
		~PlanetaryHeightmapData();

		/// Get a page/tile heightmap.
		/// Parameters are indices.
		const PlanetaryPageHeightmap *getHeightmap(unsigned int planet,unsigned int zone, unsigned int pageX, unsigned int pageZ, unsigned int LOD = 0) const;
		
		/// Get a zone heightmap.
		/// Parameters are indices.
		const PlanetaryZoneHeightmap *getZoneHeightmap(unsigned int planet, unsigned int zone) const; 

		/// Clear the heightmap cache
		void clear();

	private:
		/// Scenemanager object
		PlanetarySceneManager *mSceneMgr;

		/// Options object
		PlanetaryOptions *mOptions;

		/// Cached page/tile heightmaps
		mutable std::list<HEIGHTMAPDATA *> mCachedHeightmaps;
		/// Cached zone heightmaps
		mutable std::list<ZONEHEIGHTMAPDATA *> mCachedZoneHeightmaps;
	};
}

#endif
